package rabbitmq.test;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * 声明组件 创建交换机 创建队列
 */
public class Declare {
    //声明短连接全局变量
    private Channel channel;

    /**
     * @Before的案例方法 是在所有的单元测试test方法之前执行
     */
    @Before
    public void init() throws IOException, TimeoutException {
        //通过java客户端建立和rabbitmq的连接
        ConnectionFactory factory = new ConnectionFactory();
        //给工厂提供链接属性 ip:port
        factory.setHost("localhost");
        factory.setPort(5672);
        //权限账号
        factory.setUsername("guest");
        factory.setPassword("guest");
        //虚拟主机,每隔连接工厂,由一个程序管理,程序所属的环境 连接的虚拟主机 virtual_host不同
        //实现不同环境的数据隔离 默认就是/
        factory.setVirtualHost("/");
        Connection connection = factory.newConnection();
        //可以从长连接获取短链接
        channel = connection.createChannel();
    }

    //声明队列
    @Test
    public void queueDeclare() throws IOException {
        /**
         *String queue: 创建的队列名称,在虚拟主机中 只能存在唯一名称
         *Boolean durable: 队列是否持久化 true在rabbitmq重启之后 队列保持存在 false不存在
         *Boolean exclusive: 队列是绑定当前连接对象(独占 专属) true别的链接无法操作队列 false所有连接都可以操作队列
         *Boolean autoDelete: 队列是否自动删除 true队列从第一个监听消费者开始计算,到最后一个消费者断开连接,自动删除 false不删除
         *Map<String,Object> args: 队列特性参数 value三种 string (long double integer) boolean
         *key值是固定的,可以表示rabbitmq声明队列的特性,比如队列最大长度(最多可以容纳多少个消息)
         */
        channel.queueDeclare("queue02",false,false,false,null);
    }
    @Test
    public void queueDeclareArgs() throws IOException {
        /**
         * 队列最大未使用时间
         * x-expires=10000
         * x-max-length=10 默认drop head
         */
        Map<String,Object> args=new HashMap<>();
        args.put("x-expires",10000);
        args.put("x-max-length",10);
        channel.queueDeclare(
                "queue05",
                false,
                false,
                false,args);
    }
    //声明交换机
    @Test
    public void exchangeDeclare() throws IOException {
        /**
         * String exchange: 交换机名称,名称唯一
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 true持久化 false不持久化
         * Boolean autoDelete: 交换机是否自动删除 true自动删除 false不删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("direct_ex","direct",false,false,null);
        channel.queueBind("queue01","direct_ex","北京");
        channel.queueBind("queue02","direct_ex","上海");
    }

    @Test
    public void exchangeDeclareFanout() throws IOException {
        channel.exchangeDeclare("fanout_ex","fanout",false,false,null);
        channel.queueBind("queue01","fanout_ex","北京");
        channel.queueBind("queue02","fanout_ex","上海");
    }
    //声明主题交换机
    @Test
    public void exchangeDeclareTopic() throws IOException {
        channel.exchangeDeclare("topic_ex_01","topic",false,false,null);
        //queue01 queue02使用明确的路由绑定
        channel.queueBind("queue01","topic_ex_01","北京");
        channel.queueBind("queue02","topic_ex_01","上海");
        channel.exchangeDeclare("topic_ex_02","topic",false,false,null);
        //使用统配符号
        channel.queueBind("queue01","topic_ex_02","*.北京.*");
        channel.queueBind("queue02","topic_ex_02","*.上海.#");

    }
}
